package com.fingard.dsp.bank.directbank.fngrd01;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fingard.constant.Format;
import com.fingard.crypto.DigestHelper;
import com.fingard.diagnostics.LogHelper;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.bankInterface.ICloseOrder;
import com.fingard.dsp.bank.directbank.fngrd01.util.HttpUtils;
import com.fingard.dsp.bank.reqrespobj.closeorder.CloseOrderState;
import com.fingard.dsp.bank.reqrespobj.closeorder.ReqCloseOrder;
import com.fingard.dsp.bank.reqrespobj.closeorder.RetAtsCloseOrder;
import com.fingard.text.StringHelper;

import java.util.Date;
import java.util.HashMap;

/**
 * 
 * 融汇扫码付统一关单
 * 
 * 开发文档： WebAPI接入技术方案V1.6.doc
 * 开发接口： 2.3.3	关闭订单
 * 开发时间：2017年08月06日
 * 开发作者：方海洪
 * 
 * 应用场景：
 * 		此接口主要用于关闭相应的订单，包括支付宝、微信订单，请确保订单号在商户系统内唯一，不按渠道区分。
 * 		1、商户订单支付失败需要生成新单号重新发起支付，要对原订单号调用关单，避免重复支付；
 * 		2、系统下单后，用户支付超时，系统退出不再受理，避免用户继续，请调用关单接口。
 * 
 */
public class FnGrd01CloseOrder extends FnGrd01Base implements ICloseOrder {
	/**
	 * 扫码付关单
	 */
	@Override
	public RetAtsCloseOrder closeOrder(ReqCloseOrder p_req) {
        if ("APPORDER01".equals(p_req.reqHeader.commandCode)) {
            return appCloseOrder(p_req);
        } else {
            return closeOtherOrder(p_req);
        }
    }

	/**
	 * 融易保APP支付关单
	 * 
	 * @param p_req
	 * @return
	 */
    public RetAtsCloseOrder appCloseOrder(ReqCloseOrder p_req) {
        RetAtsCloseOrder retAts = new RetAtsCloseOrder(p_req.reqHeader);
        retAts.rdSeq = p_req.rdSeq;
        
        try {
        	ActSetItem actItem = getBankConfig().getActSetItem(p_req.ownAct, "appOrder");
            if (actItem != null) {
            	HashMap<String, Object> reqMap = new HashMap<String, Object>();

                reqMap.put("enterpriseNum", actItem.inMerchantId);
                reqMap.put("method", "closeOrder");
                reqMap.put("format", "JSON");
                reqMap.put("charset", getCharset());
                reqMap.put("signType", "MD5");
                reqMap.put("transSeqID", Format.DateTime17SSSFormat.format(new Date()));
                reqMap.put("version", "1.0");
                
                HashMap<String, String> bizContentMap = new HashMap<String, String>();
                bizContentMap.put("exchangeNo", p_req.rdSeq);
                bizContentMap.put("fgTradeNo", "");
                bizContentMap.put("mchId", "");
                bizContentMap.put("systemType", "UNKNOW");
                reqMap.put("bizContent", bizContentMap);
                
                String signStr = oriSignStr(reqMap, actItem.saltKey);
                WriteBankLogLn2("签名原始数据:\r\n" + signStr);
//                System.out.println("签名原始串:\r\n" + signStr);
                
                String signature = DigestHelper.cryptoMD5RetHexStr(signStr.getBytes(getCharset()));
                reqMap.put("sign", signature);
                String reqPostJson = getPostJson(reqMap);
                WriteBankLogLn2("请求数据:\r\n" + reqPostJson);
//                System.out.println("请求数据:\r\n" + reqPostJson);
                
        		String tmpStrRet = HttpUtils.doPost(bankFront.getUrl("appCloseOrder"), "", reqPostJson.getBytes(getCharset()), 50000, 50000, "", 0);
        		WriteBankLogStep3(tmpStrRet);
//        		System.out.println("返回数据:\r\n"+tmpStrRet);
            	
        		JSONObject tmpRespJson = JSONObject.parseObject(tmpStrRet);
        		
                retAts.respCode = "0";
                retAts.respInfo = tmpRespJson.getString("msg");
                
                String tmpRespCode = tmpRespJson.getString("code");
                if ("0".equals(tmpRespCode)) {
                	String bizCode = tmpRespJson.getString("bizCode");
                	String bizMsg = tmpRespJson.getString("bizMsg");
                	if (StringHelper.hasAnyChar(bizMsg)) {
                		retAts.respInfo = bizMsg;
                	}
                	if ("0".equals(bizCode) || bizMsg.contains("记录不存在") || bizMsg.contains("缴费单不存在")) {
                        retAts.closeState = CloseOrderState.Close_Success;
                    } else {
                        retAts.closeState = CloseOrderState.Close_Fail;
                        retAts.errorCode = bizCode;
                        retAts.errorMsg = bizMsg;
                    }
                } else {
                	retAts.respCode = "-1";
                    retAts.respInfo = tmpRespJson.getString("msg");
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到账号[" + p_req.ownAct + "]相应商户配置信息!";
            }
        } catch (Exception ex) {
        	ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    public RetAtsCloseOrder closeOtherOrder(ReqCloseOrder p_req) {

        RetAtsCloseOrder retAts = new RetAtsCloseOrder(p_req.reqHeader);
        retAts.rdSeq = p_req.rdSeq;
        try {
            ActSetItem actItem = getBankConfig().getActSetItemByAny(p_req.ownAct, p_req.merchantId,	p_req.appId, "unifiedorder");
            if (actItem != null) {
                // 关单业务参数

                /** 保融分配的代表某个企业的编号 */
                String enterpriseNum = actItem.inMerchantId;
                /** 商户号 */
                String mchId = actItem.merchantId;
                /** 商户订单号 */
                String outTradeNo = p_req.rdSeq;
                /** 随机字符串 */
                String nonceStr = get_nonce_str();
                /** 签名 */
                String signature = "";

                HashMap<String, String> mapParams = new HashMap<String, String>();
                mapParams.put("EnterpriseNum", enterpriseNum);
                mapParams.put("MchId", mchId);
                mapParams.put("OutTradeNo", outTradeNo);
                mapParams.put("NonceStr", nonceStr);

                // 签名
                String signStr = getSignStr(mapParams, actItem.saltKey);
                signature = signFnGrd(actItem, signStr);

                mapParams.put("Signature", signature);

                // post请求数据
                String reqPostJson = getReqPostJson(mapParams);
                String reqSendData = getReqSendData(enterpriseNum, reqPostJson);

                String url = bankFront.getUrl("CloseQRPay");

                // 发融汇
                String[] tmpStrRet = sendToFnGrd(reqSendData, url);

                // 解析融汇返回
                if (tmpStrRet[0].length() == 0) {
                    if (tmpStrRet[1].indexOf("Status") > 0) {
                        JSONObject respJSON = JSON.parseObject(tmpStrRet[1]);

                        String status = respJSON.getString("Status");
                        if ("-1".equals(status)) {
                            retAts.respCode = "-1";
                            retAts.respInfo = respJSON.getString("ReturnMsg");

                            return retAts;
                        }
                    } else {
                        String respStr = getRespPostData(tmpStrRet[1]);

                        JSONObject respJSONObj = JSON.parseObject(respStr);

                        retAts.respCode = "0";
                        retAts.respInfo = respJSONObj.getString("ReturnMsg");

                        String status = respJSONObj.getString("Status");
                        if ("0".equals(status) || "501".equals(status)) {
                            retAts.closeState = CloseOrderState.Close_Success;
                            retAts.respInfo = "订单关闭成功";
                        } else {
                            retAts.closeState = CloseOrderState.Close_Fail;
                            retAts.errorCode = status;
                            retAts.errorMsg = respJSONObj.getString("ReturnMsg");
                        }
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpStrRet[1];
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到相应的账户、商户或公众号的配置信息";
            }
        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.getMessage();

            WriteBankLogLn("交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
        }

        return retAts;
    }


}
